package org.tntbase.antxmlunit;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.Difference;
import org.custommonkey.xmlunit.XMLUnit;
import org.xml.sax.InputSource;

import java.util.List;

/**
 * User: detonator
 * Date: 5/4/11
 * Time: 3:47 PM
 */
public class XMLDiffTask extends Task {
    private String orig;
    private String result;
    private boolean failonerror = false;


    public XMLDiffTask() {
        XMLUnit.setIgnoreDiffBetweenTextAndCDATA(true);
        XMLUnit.setIgnoreWhitespace(true);
        XMLUnit.setIgnoreAttributeOrder(true);
        XMLUnit.setIgnoreComments(true);
        XMLUnit.setNormalize(true);
        XMLUnit.setExpandEntityReferences(true);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void execute() throws BuildException {
        InputSource isLeft = new InputSource(orig);
        InputSource isRight = new InputSource(result);
        try {
            Diff myDiff = new Diff(isLeft, isRight);
            if (myDiff.similar()) {
                System.out.println(String.format("File %s is OK!", result));
            } else {
                DetailedDiff dd = new DetailedDiff(myDiff);
                List<Difference> diffs = dd.getAllDifferences();
                String message = String.format("File %s is different from the desired result: %s", result, diffs);
                if(failonerror) {
                    throw new BuildException();
                } else {
                    System.out.println(message);
                }
            }
        } catch (Throwable e) {
            throw new BuildException(String.format("The following error occurred while processing %s: %s", result, e.getMessage()));
        }
    }

    public String getOrig() {
        return orig;
    }

    public void setOrig(String orig) {
        this.orig = orig;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public boolean isFailonerror() {
        return failonerror;
    }

    public void setFailonerror(boolean failonerror) {
        this.failonerror = failonerror;
    }
}
